﻿using System.Collections.Generic;
using System.Linq.Expressions;
using Domain.Infrastructure;
using Microsoft.EntityFrameworkCore;

namespace System.Repository.Base
{
    public abstract class RepositoryDomain<TDomainEntity, TDEntity> : RepositoryBase<TDEntity>
        where TDomainEntity : class, new()
        where TDEntity : class, new()
    {
        protected RepositoryDomain(IDbContextConfig config) : base(config)
        {
        }

        #region 如果为了执行效率 可以考虑重新 此方法

        /// <summary>
        ///  数据库模型 转 领域模型 
        /// </summary>
        /// <param name="data">数据库模型</param>
        /// <param name="domain">领域模型</param>
        /// <returns></returns>
        public virtual TDomainEntity AutoCopy(TDomainEntity domain, TDEntity data)
        {
            if (data != null)
            {

                if (domain == null)
                {
                    domain = new TDomainEntity();
                }
                return AutoSetValue.AutoCopy<TDomainEntity, TDEntity>(domain, data);
            }
            return null;
        }
        /// <summary>
        ///  领域模型 转数据库模型
        /// </summary>
        /// <param name="data">数据库模型</param>
        /// <param name="domain">领域模型</param>
        /// <returns></returns>
        public virtual TDEntity AutoCopy(TDEntity data, TDomainEntity domain)
        {

            if (domain != null)
            {
                if (data == null)
                {
                    data = new TDEntity();
                }
                return AutoSetValue.AutoCopy<TDEntity, TDomainEntity>(data, domain);
            }
            return null;
        }
        /// <summary>
        /// list 数据库模型 转list domain模型
        /// </summary>
        /// <param name="list"></param>
        /// <param name="temp"></param>
        /// <returns></returns>
        public List<TDomainEntity> GetList(List<TDomainEntity> list, List<TDEntity> temp)
        {
            foreach (var item in temp)
            {
                list.Add(AutoCopy(null, item));
            }
            return list;
        }
        #endregion

        #region 实现接口 

        public virtual bool Insert(TDomainEntity entity)
        {
            TDEntity model = AutoCopy(null, entity);
            return Insert(model);
        }

        public virtual bool Insert(List<TDomainEntity> entitys)
        {
            return Insert(entitys);
        }
        public abstract bool Update(TDomainEntity entity);

        public virtual bool Delete(TDomainEntity entity)
        {
            TDEntity model = AutoCopy(null, entity);
            return Delete(model);
        }
        public new virtual TDomainEntity GetEntity(string keyValue)
        {
            TDEntity model = GetModel(keyValue);
            TDomainEntity entity = AutoCopy(null, model);
            return entity;
        }
        public virtual TDomainEntity GetEntity(Expression<Func<TDEntity, bool>> predicate)
        {
            TDEntity model = GetModel(predicate);
            TDomainEntity entity = AutoCopy(null, model);
            return entity;
        }
        public new virtual List<TDomainEntity> GetList()
        {
            List<TDomainEntity> list = new List<TDomainEntity>();
            List<TDEntity> temp = base.GetList();
            return GetList(list, temp);
        }
        public new virtual List<TDomainEntity> GetList(Pagination pagination)
        {
            List<TDomainEntity> list = new List<TDomainEntity>();
            List<TDEntity> temp = FindList(pagination);
            return GetList(list, temp);
        }
      

        //public virtual List<TDomainEntity> GetList(Expression<Func<TDEntity, bool>> predicate)
        //{
        //    List<TDomainEntity> list = new List<TDomainEntity>();
        //    List<TDEntity> temp = IQueryable(predicate).ToList();

        //    return GetList(list, temp);
        //}
        public virtual List<TDomainEntity> GetList(Expression<Func<TDEntity, bool>> predicate, Pagination pagination)
        {
            List<TDomainEntity> list = new List<TDomainEntity>();
            List<TDEntity> temp = FindList(predicate, pagination);
            return GetList(list, temp);
        }
        ///// <summary>
        ///// list 数据库模型 转list domain模型
        ///// </summary>
        ///// <param name="list"></param>
        ///// <param name="temp"></param>
        ///// <returns></returns>
        //public List<TDomainEntity> GetList(List<TDomainEntity> list, List<TDEntity> temp)
        //{
        //    // ReSharper disable once LoopCanBeConvertedToQuery
        //    foreach (var item in temp)
        //    {
        //        list.Add(AutoCopy(null, item));
        //    }
        //    return list;
        //}
        public virtual List<TDomainEntity> GetList(Expression<Func<TDEntity, bool>> predicate)
        {
            List<TDomainEntity> list = new List<TDomainEntity>();
            List<TDEntity> temp = base.GetList(predicate);

            return GetList(list, temp);
        }

        #endregion



    }

}
